#pragma once

#include<iostream>
#include<string>
#include<sstream>
#include<memory>
#include<jsoncpp/json/json.h>

const std::string Sep = "\r\n";

//在序列化前用: {Json} -> len\r\n{Json}\r\n
bool Encode(std::string& message)
{
    if(message.size() == 0) return false;
    //len\r\n{Json}\r\n
    std::string package = std::to_string(message.size()) + Sep + message + Sep;
    message  = package;
    return true;
}
//序列化之后用
//len\r\n{Json}\r\n
bool Decode(std::string& package, std::string* content)
{
    auto pos = package.find(Sep);
    if(pos == std::string::npos)
        return false;

    std::string content_len_str = package.substr(0, pos);
    int content_len = std::stoi(content_len_str);
    int full_length = content_len_str.size() + content_len + 2*Sep.size();

    if(package.size() < full_length)    return false;

    *content = package.substr(pos+Sep.size(), content_len);

    package.erase(0, full_length);
    return true;
}

class Request
{
public:
    Request(){}
    Request(int x, int y, char oper):_x(x), _y(y), _oper(oper)
    {}
    bool Serialize(std::string& out_string)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;

        Json::StreamWriterBuilder wb;
        std::unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        std::stringstream ss;
        w->write(root, &ss);
        out_string = ss.str();

        return true;
    }
    bool Deserialize(std::string& in_string)
    {
        Json::Value root;
        Json::Reader reader;
        bool parsingSuccessful = reader.parse(in_string, root);
        if(!parsingSuccessful)
        {
            std::cout<<"Failed to parse JSON:" << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();

        return true;
    }
    void Print()
    {
        std::cout<<_x<<'\n'<<_y<<'\n'<<_oper<<'\n';
    }
    int X() const {return _x;}
    int Y() const {return _y;}
    char Oper() const {return _oper;}
private:
    int _x;
    int _y;
    char _oper;
};

class Response
{
public:
    Response(){}
    Response(int result, int code=0):_result(result), _code(code)
    {}
    bool Serialize(std::string& out_string)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;

        Json::StreamWriterBuilder wb;
        std::unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        std::stringstream ss;
        w->write(root, &ss);
        out_string = ss.str();

        return true;
    }
    bool Deserialize(std::string& in_string)
    {
        Json::Value root;
        Json::Reader reader;
        bool parsingSuccessful = reader.parse(in_string, root);
        if(!parsingSuccessful)
        {
            std::cout<<"Failed to parse JSON:" << reader.getFormattedErrorMessages() << std::endl;
            return false;
        }
        _result = root["result"].asInt();
        _code = root["code"].asInt();

        return true;

    }
    int const Result(){return _result;}
    int const Code(){return _code;}
    void SetResult(int res){_result = res;}
    void SetCode(int code){_code = code;}
private:
    int _result;
    int _code;
};